package com.enqualcomm.kids.mvp.pay;

import android.app.Activity;
import android.util.Base64;

import com.alipay.sdk.app.PayTask;
import com.android.volley.BuildConfig;
import com.android.volley.codec.RSACoder;
import com.enqualcomm.kids.network.http.response.OrderResult;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.internal.Util;
import com.tencent.mm.sdk.modelpay.PayReq;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.Random;

import common.utils.GsonFactory;
import common.utils.MyLogger;
import common.utils.NetUtil;
import rx.Single;
import rx.SingleSubscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * Created by Yinzhiqun on 2016/8/1.
 */
public class PayUtil {
    private static final String ORDER_URL = "http://121.42.214.238/pay/addorder";
    private static final String ALI_NOTIFY_URL = "http://121.42.214.238/pay/alipaynotifyurl";
    private static final String WX_NOTIFY_URL = "http://121.42.214.238/pay/weixinBackNotify";
    private static final String FLAG_ALIPAY = "0";
    private static final String FLAG_WECHAT = "1";

    private static final String ALI_PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJ/C9gEBwMgXYDcP\n" +
            "kjX1oixLf8bc0bJx0hSukVVQ1J2OCgUp7goodXI2SjSrtw+qzr3FJmw2vOSDyYcQ\n" +
            "nbqWuriTDEv37pooH3k/Ky4m/+TZpjbJ30fwlL4SiNF0K+5b6WaRDty3JWoIsav0\n" +
            "yZp9pqy8XM6JbBtn7ICsdksDvvDZAgMBAAECgYAjiYiTPMKXP6vlU49gdV03oSux\n" +
            "Hpl+qhbjBtnJMou46EmOUH9kvw8w8qabBL9ZutL2H46mb56g7je71ZRgVvr9jZsF\n" +
            "Cou5uMzg4YmUVQki27JZjStI886uNTN01wS6fMiIGVUXWWQUsKhiNTiluPUoUBFe\n" +
            "8IVidgNtS+lXmmZ1IQJBANLw8GdM3vPQYcQu1eynk6wEcg17EePZe4EXBtQwNcT9\n" +
            "fOKQawt1frvJu3tf23XAdAuj/iqt7FzFhv6ZGPYOfyUCQQDB41Phib0Xdrbapfu+\n" +
            "D0Q0LauY8HLlXegz7AxmJVk+U9JUCQ5ouHzCpjZEeFcUEivQeiy9xph9Foz0cmZa\n" +
            "kaalAkAkliOsVxnoggEjDNiP5nTnhhHeIrV0ppkUR9EoZoA8/ZZ2mYPnheaIXbIF\n" +
            "8RdYchvulPAVqPrxEFWcvSMmMld9AkEAvhSZ1ZDtmqU92tnDFa9t1CG6CzQf0BHi\n" +
            "ZZTTCwkultYia1R9ldjYJxRAO5wm8nxmC/rbBio+sNN82OGWys/kKQJAG2Hd0sbj\n" +
            "X2JkPzTOUxyBGvg54uS5XmIziuNxGj2XWjhnvRo1Wyc8LVvNRhfJU87AY++A0ccW\n" +
            "IZfVnOEy4lmevw==";
//    private static final String ALI_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnxj/9qwVfgoUh/y2W89L6BkRAFljhNhgPdyPuBV64bfQNN1PjbCzkIM6qRdKBoLPXmKKMiFYnkd6rAoprih3/PrQEB/VsW8OoM8fxn67UDYuyBTqA23MML9q1+ilIZwBC2AQ2UBVOrFXfFl75p6/B5KsiNG9zpgmLCUYuLkxpLQIDAQAB";
    /*****************************
     * 西瓜皮
     ***********************************************/
//    public static final String WX_APPID = "wxd110839a0818c66b";
//    private static final String WX_KEY = "WdjkwIOP124ajo94JK039021359uKLFd";
//    private static final String WX_MCH_ID = "1376678802";

    /**
     * 喜书郎
     ***********************************************/
    public static final String WX_APPID = com.enqualcomm.kids.BuildConfig.WX_APPID;
    private static final String WX_KEY = com.enqualcomm.kids.BuildConfig.WX_KEY;
    private static final String WX_MCH_ID = com.enqualcomm.kids.BuildConfig.WX_MCH_ID;

    /*****************************
     * 儿童天使V
     ***********************************************/
//    public static final String WX_APPID = "wxe259dfe6e50dd472";
//    private static final String WX_KEY = "Eqdnk07u234r70LFIneojkoji43579of";
//    private static final String WX_MCH_ID = "1394462102";


    private static OkHttpClient mOkHttpClient = new OkHttpClient();

    /**
     * 如果付款成功，返回orderid，否则返回null
     */
    public static Single<String> alipay(final Activity activity, String userkey, String userid, String imei, String productID) {
        //1.访问后台服务器生成订单
        //2.拼接支付宝需要的orderInfo
        //3.调用支付sdk，得到PayResult
        //4.验证PayResult

        return getOrder(userkey, userid, imei, productID, FLAG_ALIPAY)
                .map(new Func1<OrderResult, String>() {
                    @Override
                    public String call(OrderResult orderResult) {
                        if (orderResult != null) {
                            String orderInfo = new StringBuilder().append("service=\"mobile.securitypay.pay\"&partner=\"2088421559266349\"&_input_charset=\"utf-8\"&notify_url=\"")
                                    .append(ALI_NOTIFY_URL).append("\"&payment_type=\"1\"&body=\"智能手表服务费\"&out_trade_no=\"")
                                    .append(orderResult.orderid).append("\"&subject=\"").append(orderResult.title).append("\"&total_fee=\"").append(orderResult.money)
                                    .append("\"&seller_id=\"eqc_pay@enqualcomm.com\"").toString();

                            try {
                                String sign = RSACoder.sign(orderInfo.getBytes(), Base64.decode(ALI_PRIVATE_KEY, Base64.DEFAULT));
                                sign = URLEncoder.encode(sign, "UTF-8");
                                return orderInfo + "&sign_type=\"RSA\"&sign=\"" + sign + "\"";
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        return null;
                    }
                }).map(new Func1<String, PayResult>() {
                    @Override
                    public PayResult call(String orderInfo) {
                        if (orderInfo != null) {
                            PayTask payTask = new PayTask(activity);
                            String payResult = payTask.pay(orderInfo, true);
                            return new PayResult(payResult);
                        }
                        return null;
                    }
                }).map(new Func1<PayResult, String>() {
                    @Override
                    public String call(PayResult payResult) {
                        if (payResult != null) {
                            String resultStatus = payResult.getResultStatus();
                            if ("9000".equals(resultStatus)) {
                                String result = payResult.getResult();
                                if (result.contains("&success=\"true\"")) {
                                    int start = result.indexOf("&out_trade_no=\"") + 15;
                                    int end = result.indexOf("\"", start);
                                    String orderid = result.substring(start, end);
                                    return orderid;
                                }
                            }
                        }
                        return null;
                    }
                })
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    public static Single<String> wxpay(final Activity activity, String userkey, String userid, String terminalid, String productID) {
        //1.访问后台服务器生成订单
        //2.访问微信后台生成订单
        //3.发起支付

        return getOrder(userkey, userid, terminalid, productID, FLAG_WECHAT)
                .map(new Func1<OrderResult, WXPrePay>() {
                    @Override
                    public WXPrePay call(OrderResult orderResult) {
                        if (orderResult != null) {
                            String param = getWXParam(orderResult, NetUtil.getIp(activity));

                            Request request = new Request.Builder()
                                    .url("https://api.mch.weixin.qq.com/pay/unifiedorder")
                                    .post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded; charset=UTF-8"), param.getBytes()))
                                    .build();

                            Call call = mOkHttpClient.newCall(request);
                            try {
                                Response response = call.execute();
                                if (response.code() == 200) {
                                    String string = response.body().string();
                                    MyLogger.jLog().i(string);
                                    return new WXPrePay(string, orderResult.orderid);
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        return null;
                    }
                }).map(new Func1<WXPrePay, String>() {
                    @Override
                    public String call(WXPrePay wxPrePay) {
                        if (wxPrePay != null && "SUCCESS".equals(wxPrePay.return_code) && "SUCCESS".equals(wxPrePay.result_code)) {
                            IWXAPI wxapi = WXAPIFactory.createWXAPI(activity, WX_APPID);
                            wxapi.registerApp(WX_APPID);
                            PayReq payReq = new PayReq();
                            payReq.appId = WX_APPID;
                            payReq.partnerId = WX_MCH_ID;
                            payReq.prepayId = wxPrePay.prepay_id;
                            payReq.packageValue = "Sign=WXPay";
                            payReq.nonceStr = Util.md5Hex("cyp123" + new Random().nextInt(10000));
                            payReq.timeStamp = String.valueOf(System.currentTimeMillis() / 1000);

                            String s = new StringBuilder().append("appid=").append(payReq.appId).append("&noncestr=").append(payReq.nonceStr)
                                    .append("&package=").append(payReq.packageValue).append("&partnerid=").append(payReq.partnerId)
                                    .append("&prepayid=").append(payReq.prepayId).append("&timestamp=").append(payReq.timeStamp)
                                    .append("&key=").append(WX_KEY).toString();
                            payReq.sign = Util.md5Hex(s).toUpperCase();
                            wxapi.sendReq(payReq);
                            return wxPrePay.orderid;
                        }
                        return null;
                    }
                })
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    private static String getWXParam(OrderResult orderResult, String spbill_create_ip) {
//        MyLogger.jLog().i("ip地址是"+spbill_create_ip);
        String body = orderResult.title;
        String nonce_str = Util.md5Hex("cyp123" + new Random().nextInt(10000));
        String out_trade_no = orderResult.orderid;
        int total_fee = (int) (Float.parseFloat(orderResult.money) * 100);
        String trade_type = "APP";

        StringBuilder builder = new StringBuilder();
        String stringSignTemp = builder.append("appid=").append(WX_APPID).append("&body=").append(body).append("&mch_id=").append(WX_MCH_ID)
                .append("&nonce_str=").append(nonce_str).append("&notify_url=").append(WX_NOTIFY_URL).append("&out_trade_no=").append(out_trade_no)
                .append("&spbill_create_ip=").append(spbill_create_ip).append("&total_fee=").append(total_fee).append("&trade_type=").append(trade_type)
                .append("&key=").append(WX_KEY).toString();


        String sign = Util.md5Hex(stringSignTemp).toUpperCase();
        builder.setLength(0);

        return builder.append("<xml>")
                .append("<appid>").append(WX_APPID).append("</appid>")
                .append("<mch_id>").append(WX_MCH_ID).append("</mch_id>")
                .append("<nonce_str>").append(nonce_str).append("</nonce_str>")
                .append("<sign>").append(sign).append("</sign>")
                .append("<body>").append(body).append("</body>")
                .append("<out_trade_no>").append(out_trade_no).append("</out_trade_no>")
                .append("<total_fee>").append(total_fee).append("</total_fee>")
                .append("<spbill_create_ip>").append(spbill_create_ip).append("</spbill_create_ip>")
                .append("<notify_url>").append(WX_NOTIFY_URL).append("</notify_url>")
                .append("<trade_type>").append(trade_type).append("</trade_type>")
                .append("</xml>").toString();
    }

    private static Single<OrderResult> getOrder(final String userkey, final String userid, final String terminalid, final String productID, final String flag) {
        return Single.create(new Single.OnSubscribe<OrderResult>() {
            @Override
            public void call(SingleSubscriber<? super OrderResult> singleSubscriber) {
                StringBuilder builder = new StringBuilder();
                builder.append("userkey=").append(userkey).append("&userid=").append(userid).append("&terminalid=").append(terminalid).append("&productpayid=").append(productID)
                        .append("&flag=").append(flag).append("&host=").append(BuildConfig.IP).append("&port=").append(BuildConfig.PORT);

                Request request = new Request.Builder()
                        .url(ORDER_URL)
                        .post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded; charset=UTF-8"), builder.toString().getBytes()))
                        .build();
                Call call = mOkHttpClient.newCall(request);
                try {
                    Response response = call.execute();
                    if (response.code() == 200) {
                        String string = response.body().string();
                        MyLogger.jLog().i(string);
                        OrderResult orderResult = GsonFactory.newInstance().fromJson(string, OrderResult.class);
                        singleSubscriber.onSuccess(orderResult);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

                singleSubscriber.onSuccess(null);
            }
        });
    }


}
